package com.tcfvic.client.panels.widgets.widgetcontents;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.tcfvic.client.PersonService;
import com.tcfvic.client.PersonServiceAsync;
import com.tcfvic.client.panels.widgets.SimpleMessagePopup;
import com.tcfvic.client.panels.widgets.TCFWidgetContent;
import com.tcfvic.client.pojos.Address;
import com.tcfvic.client.pojos.Person;
import com.tcfvic.client.pojos.Personaddress;
import com.tcfvic.client.tools.Month;
import com.tcfvic.client.tools.State;
import com.tcfvic.client.tools.Tools;

public final class PersonTab extends AbstractDataEntryWidgets implements
		TCFWidgetContent {

	public static final DateTimeFormat df = DateTimeFormat
			.getFormat("dd/MM/yyyy");

	private TextBox firstNameTextBox = new TextBox();
	private TextBox surnameTextBox = new TextBox();
	private TextBox landline = new TextBox();
	private TextBox mobile = new TextBox();
	private TextBox email = new TextBox();
	private ListBox gender = new ListBox();
	private TextBox streetLine1 = new TextBox();
	private TextBox streetLine2 = new TextBox();
	private TextBox suburb = new TextBox();
	private TextBox unionMemberNo = new TextBox();
	private TextArea notes = new TextArea();
	private ListBox state = null;
	private TextBox postcode = new TextBox();
	private ListBox day = null;
	private ListBox month = null;
	private ListBox year = null;
	private Button saveButton = new Button("Save");
	private TextBox personId = new TextBox();
	private TextBox addressId = new TextBox();
	private ListBox countryOfOrigin = new ListBox();
	private ListBox dayMigration = null;
	private ListBox monthMigration = null;
	private ListBox yearMigration = null;
	private ListBox lbFirstLang = new ListBox();
	private ListBox lbFormalEdHigh = new ListBox();
	private ListBox lbFormalEdCountry = new ListBox();
	private HTML ageLabel = new HTML("<b>Date of birth</b>");
	// private FlexTable availableFunding = new FlexTable();

	private final PersonServiceAsync personService = GWT
			.create(PersonService.class);

	@Override
	public String getName() {
		return "Info";
	}

	@Override
	public void initialise() {
		clear();
	}

	public String getAge(Date dob) {
		if (dob == null) {
			return "Date of birth";
		}

		String age = "";
		long diff = System.currentTimeMillis() - dob.getTime();
		age = String.valueOf(diff / 1000 / 60 / 60 / 24 / 365D);
		age = age.substring(0, age.indexOf("."));
		return "Date of birth \n(age: " + age + ")";
	}

	@Override
	public Widget getContent() {
		// Create a table to layout the form options
		FlexTable ft = new FlexTable();
		ft.setCellSpacing(4);
		ft.setWidth("100%");

		// Add some standard form options
		HTML text = new HTML("<b>Surname</b>");
		ft.setWidget(0, 0, text);
		ft.setWidget(0, 1, surnameTextBox);
		ft.setHTML(1, 0, "<b>Given names</b>");
		ft.setWidget(1, 1, firstNameTextBox);

		HorizontalPanel hp = new HorizontalPanel();
		day = Tools.getDayListBox();
		month = Tools.getMonthListBox();
		year = Tools.getYearListBox();
		hp.add(day);
		hp.add(month);
		hp.add(year);
		ft.setWidget(2, 0, ageLabel);
		ft.setWidget(2, 1, hp);

		gender = Tools.getGenderListBox();
		ft.setHTML(3, 0, "<b>Gender</b>");
		ft.setWidget(3, 1, gender);

		ft.setHTML(4, 0, "Phone 1");
		ft.setWidget(4, 1, landline);
		ft.setHTML(5, 0, "Phone 2");
		ft.setWidget(5, 1, mobile);
		ft.setHTML(6, 0, "Union member no");
		ft.setWidget(6, 1, unionMemberNo);
		notes.setVisibleLines(5);
		ft.setHTML(7, 0, "Notes");
		ft.setWidget(7, 1, notes);
		notes.setWidth("200");
		// cellFormatter.setColSpan(7, 1, 3);
		ft.setHTML(0, 2, "Street");
		ft.setWidget(0, 3, streetLine1);
		// ft.setHTML(1, 2, "Street line 2");
		// ft.setWidget(1, 3, streetLine2);
		ft.setHTML(1, 2, "Suburb");
		ft.setWidget(1, 3, suburb);
		ft.setHTML(2, 2, "State");
		state = getStatesListBox();
		ft.setWidget(2, 3, state);
		ft.setHTML(3, 2, "Postcode");
		ft.setWidget(3, 3, postcode);
		ft.setHTML(4, 2, "Email");
		ft.setWidget(4, 3, email);
		countryOfOrigin = Tools.getCountryList();
		ft.setHTML(5, 2, "Country of origin");
		ft.setWidget(5, 3, countryOfOrigin);

		dayMigration = Tools.getDayListBox();
		monthMigration = Tools.getMonthListBox();
		yearMigration = Tools.getYearListBox(1920);
		hp = new HorizontalPanel();
		hp.add(dayMigration);
		hp.add(monthMigration);
		hp.add(yearMigration);
		ft.setHTML(6, 2, "Date of migration");
		ft.setWidget(6, 3, hp);

		lbFirstLang = Tools.getLanguageList();
		ft.setHTML(7, 2, "First language");
		ft.setWidget(7, 3, lbFirstLang);

		lbFormalEdHigh = getEdLevel();
		ft.setHTML(8, 2, "Highest level");
		ft.setWidget(8, 3, lbFormalEdHigh);
		lbFormalEdCountry = Tools.getCountryList();
		ft.setHTML(9, 2, "Country");
		ft.setWidget(9, 3, lbFormalEdCountry);

		// ft.setWidget(6, 2, availableFunding);
		// cellFormatter.setColSpan(6, 2, 2);
		// cellFormatter.setRowSpan(6, 2, 10);

		saveButton.getElement().setId("saveButton");
		ft.setWidget(8, 0, saveButton);

		return ft;
	}

	public void clear() {
		lbFirstLang.setSelectedIndex(0);
		getPersonId().setText("-1");
		getAddressId().setText("");
		getFirstNameTextBox().setText("");
		getSurnameTextBox().setText("");
		getMobile().setText("");
		getLandline().setText("");
		getGender().setSelectedIndex(0);
		getEmail().setText("");
		getStreetLine1().setText("");
		getStreetLine2().setText("");
		getSuburb().setText("");
		getPostcode().setText("");
		getUnionMemberNo().setText("");
		getNotes().setText("");
		lbFormalEdHigh.setSelectedIndex(0);
		lbFormalEdCountry.setSelectedIndex(0);
		Tools.resetList(dayMigration, monthMigration, yearMigration,
				countryOfOrigin, getState(), getDay(), getMonth(), getYear());
	}

	public void updateContent(Object result) {
		if (result instanceof Person) {
			Person person = (Person) result;

			// populateFundingAmountsAvailable(person.getId());
			getPersonId().setText(String.valueOf(person.getId()));
			getFirstNameTextBox().setText(person.getFirstname());
			getSurnameTextBox().setText(person.getSurname());
			getMobile().setText(person.getMobile());
			getLandline().setText(person.getLandline());
			getGender().setSelectedIndex(
					Tools.getSelectedIndex(getGender(), person.getGender()));
			getEmail().setText(person.getEmail());
			getUnionMemberNo().setText(person.getUnionMemberNo());
			getNotes().setText(person.getNotes());
			lbFormalEdHigh.setSelectedIndex(Tools.getSelectedIndex(
					lbFormalEdHigh, person.getFormalEdHighLevel()));
			lbFormalEdCountry.setSelectedIndex(Tools.getSelectedIndex(
					lbFormalEdCountry, person.getFormalEdCountry()));
			lbFirstLang.setSelectedIndex(Tools.getSelectedIndex(lbFirstLang,
					person.getFirstLanguage()));
			countryOfOrigin.setSelectedIndex(Tools.getSelectedIndex(
					countryOfOrigin, ((Person) result).getCountryOfOrigin()));
			if (person.getDateofmigration() != null) {
				dayMigration.setSelectedIndex(Tools
						.getSelectedIndexBasedOnItem(dayMigration, Tools
								.getDay(person.getDateofmigration())));
				monthMigration.setSelectedIndex(Tools
						.getSelectedIndexBasedOnItem(monthMigration, Tools
								.getMonth(person.getDateofmigration())
								.toUpperCase()));
				yearMigration.setSelectedIndex(Tools
						.getSelectedIndexBasedOnItem(yearMigration, Tools
								.getYear(person.getDateofmigration())));
			}
			if (person.getDateofbirth() != null) {
				getDay()
						.setSelectedIndex(
								Integer.parseInt(Tools.getDay(person
										.getDateofbirth())));
				getMonth().setSelectedIndex(
						Month.valueOf(
								Tools.getMonth(person.getDateofbirth())
										.toUpperCase()).getId());
				getYear()
						.setSelectedIndex(
								Integer.parseInt(Tools.getYear(person
										.getDateofbirth())) - 1899);
				getAgeLabel().setHTML("<b>" + getAge(person.getDateofbirth()) + "</b>");
			}
			if (person.getPersonaddresses() != null
					&& person.getPersonaddresses().size() > 0) {
				for (Personaddress personAddress : person.getPersonaddresses()) {
					addressId.setText(String.valueOf(personAddress.getId()
							.getAddressId()));
					getStreetLine1().setText(
							personAddress.getAddress().getStreet());
					getStreetLine2().setText(
							personAddress.getAddress().getStreet2());
					getSuburb().setText(personAddress.getAddress().getSuburb());
					if (personAddress.getAddress().getState() != null
							&& personAddress.getAddress().getState().trim()
									.length() > 0) {
						getState().setSelectedIndex(
								State.valueOf(
										personAddress.getAddress().getState())
										.getId());
					}
					getPostcode()
							.setText(
									personAddress.getAddress().getPostcode() != null ? personAddress
											.getAddress().getPostcode()
											.toString()
											: "");
				}
			}
		}

	}

	// public void populateFundingAmountsAvailable(int personId) {
	// personService.getAvailableAmounts(personId,
	// new AsyncCallback<List<AvailableFunding>>() {
	// @Override
	// public void onSuccess(List<AvailableFunding> result) {
	// availableFunding.setHTML(0, 0,
	// "<B>Funding spent</B>");
	// int i = 1;
	// NumberFormat nf = NumberFormat.getFormat("0.00");
	// for (AvailableFunding af : result) {
	// availableFunding.setHTML(i, 0, af.getName());
	// availableFunding.setHTML(i, 1, nf.format(af
	// .getAmount()));
	// i++;
	// }
	// }
	//
	// @Override
	// public void onFailure(Throwable caught) {
	// GWT.log("Error occured getting funding amount", caught);
	//
	// }
	// });
	// }

	@Override
	public void setSaveClickHandler(ClickHandler clickHandler) {
		// Add a handler to close the DialogBox
		saveButton.addClickHandler(clickHandler);
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T> T saveContent(T t) throws Exception {
		Person personDetailsDTO = new Person();
		if (!validInput() || !minimumInput()) {
			return null;
		}
		if (getPersonId() != null && !getPersonId().getText().isEmpty()) {
			personDetailsDTO.setId(new Integer(getPersonId().getText()));
		}
		personDetailsDTO.setFirstname(getFirstNameTextBox().getText());
		personDetailsDTO.setSurname(getSurnameTextBox().getText());
		personDetailsDTO.setMobile(getMobile().getText());
		personDetailsDTO.setLandline(getLandline().getText());
		personDetailsDTO.setGender(getGender().getItemText(
				getGender().getSelectedIndex()));
		personDetailsDTO.setUnionMemberNo(getUnionMemberNo().getText());
		personDetailsDTO.setEmail(getEmail().getText());
		personDetailsDTO.setNotes(notes.getText());
		try {
			personDetailsDTO.setFormalEdHighLevel(lbFormalEdHigh
					.getItemText(lbFormalEdHigh.getSelectedIndex()));
		} catch (Exception e) {
		}
		try {
			personDetailsDTO.setFormalEdCountry(lbFormalEdCountry
					.getItemText(lbFormalEdCountry.getSelectedIndex()));
		} catch (Exception e) {
		}
		if (Tools.isValidDate(dayMigration, monthMigration, yearMigration)) {
			personDetailsDTO.setDateofmigration(Tools.parseDate(dayMigration,
					monthMigration, yearMigration));
		}
		try {
			personDetailsDTO.setCountryOfOrigin(countryOfOrigin
					.getItemText(countryOfOrigin.getSelectedIndex()));
		} catch (Exception e) {
		}
		if (Tools.isValidDate(getDay(), getMonth(), getYear())) {
			personDetailsDTO.setDateofbirth(Tools.parseDate(getDay(),
					getMonth(), getYear()));
		}

		try {
			personDetailsDTO.setFirstLanguage(lbFirstLang
					.getItemText(lbFirstLang.getSelectedIndex()));
		} catch (Exception e) {
		}

		if (Tools.checkIfAnyAreNotNull(addressId, getStreetLine1(),
				getStreetLine2(), getSuburb(), getPostcode())
				|| (getState() != null && getState().getSelectedIndex() > -1 && getState()
						.getItemText(getState().getSelectedIndex()) != null)) {
			Personaddress personAddress = new Personaddress();
			Address address = new Address();

			if (addressId != null && !addressId.getText().isEmpty()) {
				address.setId(new Integer(addressId.getText()));
			}
			address.setStreet(getStreetLine1().getText());
			address.setStreet2(getStreetLine2().getText());
			address.setSuburb(getSuburb().getText());
			if (getState() != null && getState().getSelectedIndex() > -1) {
				address.setState(getState().getItemText(
						getState().getSelectedIndex()));
			}
			if (getPostcode().getText() != null
					&& getPostcode().getText().trim().length() > 0)
				address.setPostcode(new Integer(getPostcode().getText()));
			personAddress.setAddress(address);
			Set<Personaddress> personAddresses = new HashSet<Personaddress>();
			personAddresses.add(personAddress);
			personDetailsDTO.setPersonaddresses(personAddresses);
		}
		return (T) personDetailsDTO;
	}

	public boolean validInput() {
		if (personId.getText() != null
				&& personId.getText().trim().equals("-1")) {
			new SimpleMessagePopup(
					"Please select a person or create a new record before trying to save",
					null).showPopup();
			return false;
		}
		try {
			if (postcode.getText() != null
					&& postcode.getText().trim().length() > 0) {
				Integer.parseInt(postcode.getText());
			}

		} catch (Exception e) {
			new SimpleMessagePopup("Please enter a valid 4 digit postcode",
					postcode).showPopup();
			return false;
		}
		try {
			if (Tools.checkIfSelectedValue(day, month, year)
					&& !Tools.isValidDate(day, month, year)) {
				throw new Exception();
			}
		} catch (Exception e) {
			System.err.println(e);
			new SimpleMessagePopup("The date is not valid", day).showPopup();
			return false;
		}
		return true;
	}

	public boolean minimumInput() {
		if (firstNameTextBox.getText() == null
				|| firstNameTextBox.getText().trim().length() == 0) {
			new SimpleMessagePopup("Please enter a first name",
					firstNameTextBox).showPopup();
			return false;
		}
		if (surnameTextBox.getText() == null
				|| surnameTextBox.getText().trim().length() == 0) {
			new SimpleMessagePopup("Please enter a surname", surnameTextBox)
					.showPopup();
			return false;
		}

		return true;
	}

	public TextBox getFirstNameTextBox() {
		return firstNameTextBox;
	}

	public TextBox getPersonId() {
		return personId;
	}

	public TextBox getSurnameTextBox() {
		return surnameTextBox;
	}

	public TextBox getMobile() {
		return mobile;
	}

	public TextBox getEmail() {
		return email;
	}

	public TextBox getStreetLine1() {
		return streetLine1;
	}

	public TextBox getStreetLine2() {
		return streetLine2;
	}

	public TextBox getSuburb() {
		return suburb;
	}

	public ListBox getState() {
		return state;
	}

	public TextBox getPostcode() {
		return postcode;
	}

	public ListBox getDay() {
		return day;
	}

	public ListBox getMonth() {
		return month;
	}

	public ListBox getYear() {
		return year;
	}

	public Button getSaveButton() {
		return saveButton;
	}

	public TextBox getLandline() {
		return landline;
	}

	public ListBox getGender() {
		return gender;
	}

	public TextBox getAddressId() {
		return addressId;
	}

	// public FlexTable getAvailableFunding() {
	// return availableFunding;
	// }

	public PersonServiceAsync getPersonService() {
		return personService;
	}

	public TextBox getUnionMemberNo() {
		return unionMemberNo;
	}

	public TextArea getNotes() {
		return notes;
	}

	public HTML getAgeLabel() {
		return ageLabel;
	}

	@Override
	public void createNewRecord() {
		clear();
		getPersonId().setText("");
	}

	@Override
	public void onSave(Person person) {
		if (person != null) {
			personId.setText(String.valueOf(person.getId()));
		}
	}

	private ListBox getEdLevel() {
		ListBox lb = new ListBox();
		lb.addItem("");
		lb.addItem("Primary");
		lb.addItem("Secondary");
		lb.addItem("Tertiary");
		lb.addItem("Tafe");
		return lb;
	}

}
